/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package View;

import Action.MessageListener;
import Model.Lane;
import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.JTextField;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

/**
 *Main Frame for construction of GUI
 * @author Pro
 */
public class CarsCrossingFrame extends JFrame {

    private Lane[] lanes;
    private CarsDisplay carsDisplay;
    private JButton runPause, exit, save, load;
    private JTextField hLanesTxt, vLanesTxt;
    private JSlider hProb, vProb;
    private int length, width, hLanes, vLanes, y, intCatch;
    private MessageListener listener;
    private String txtCatch;
    private JPanel mainFrame, display, buttonsPanel, bpLevel1, bpLevel2, bpLevel3, startPanel, exitPanel;
    private JLabel hLaneLabel, vLaneLabel;

    /**
     * Constructor with single argument of Lane class
     * @param newLanes
     */
    public CarsCrossingFrame(Lane[] newLanes) {

        setTitle("Cars Crossing, not crashing.. :-{");
        lanes = newLanes;
        length = 800;
        width = 800;
        carsDisplay = new CarsDisplay(lanes);
        hLaneLabel = new JLabel("Horizontal Lanes (1-3)<==========> Probability: %");
        vLaneLabel = new JLabel("Verticall Lanes (1-3)<===========> Probability: %");
        hProb = new JSlider(0, 100, 100);
        vProb = new JSlider(0, 100, 100);
        runPause = new JButton("Start//Stop");
        exit = new JButton("Exit");
        save = new JButton("Save");
        load = new JButton("Load");
        hLanesTxt = new JTextField("3", 5);
        vLanesTxt = new JTextField("3", 5);

        mainFrame = new JPanel();
        mainFrame.setLayout(new BorderLayout());
        display = new JPanel();
        buttonsPanel = new JPanel();
        buttonsPanel.setLayout(new GridLayout(3, 1));
        bpLevel1 = new JPanel();
        bpLevel1.setLayout(new GridLayout(1, 3));
        bpLevel2 = new JPanel();
        bpLevel2.setLayout(new GridLayout(1, 3));
        bpLevel3 = new JPanel();
        bpLevel3.setLayout(new GridLayout(1, 4));
        exitPanel = new JPanel();
        startPanel = new JPanel();

        add(mainFrame);
        mainFrame.add(display, BorderLayout.CENTER);
        mainFrame.add(buttonsPanel, BorderLayout.SOUTH);
        display.add(carsDisplay);
        buttonsPanel.add(bpLevel1);
        buttonsPanel.add(bpLevel2);
        buttonsPanel.add(bpLevel3);
        bpLevel1.add(hLanesTxt);
        bpLevel1.add(hLaneLabel);
        bpLevel1.add(hProb);
        bpLevel2.add(vLanesTxt);
        bpLevel2.add(vLaneLabel);
        bpLevel2.add(vProb);
        bpLevel3.add(save);
        bpLevel3.add(load);
        bpLevel3.add(runPause);
        bpLevel3.add(exit);

        hProb.setPaintLabels(true);
        hProb.setMajorTickSpacing(25);
        hProb.setMinorTickSpacing(5);
        hProb.setPaintTicks(true);
        hProb.setPaintLabels(true);
        vProb.setMajorTickSpacing(25);
        vProb.setMinorTickSpacing(5);
        vProb.setPaintTicks(true);
        vProb.setPaintLabels(true);

        exit.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {

                System.out.println("Exited properly yay!");
                System.exit(0);
            }
        });

        runPause.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {

  //              System.out.println("Start/Stop");
                listener.messageAction("startStop");
            }
        });

        save.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {

                 listener.messageAction("save");
            }
        });

        load.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {

                listener.messageAction("load");
            }
        });

        hLanesTxt.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {

                txtCatch = hLanesTxt.getText();


                while (true) {

                    try {
                        intCatch = Integer.parseInt(txtCatch);

                        if ((intCatch > 0) && (intCatch < 4)) {

                            listener.messageAction("hLanes", intCatch, lanes[0].getvLanes());
                            hLanes = intCatch;
                            carsDisplay = new CarsDisplay(lanes);
                            display.removeAll();
                            display.add(carsDisplay);
                            pack();
                            break;

                        } else {

                            hLanesTxt.setText("INVALID ENTRY::"+ txtCatch+":: Enter a Value from 1-3" );

                            break;
                        }

                    } catch (Exception p) {
                        hLanesTxt.setText("INVALID ENTRY::"+ txtCatch+":: Enter a Value from 1-3" );
                        break;
                    }
                }
            }
        });

        vLanesTxt.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {

                txtCatch = vLanesTxt.getText();

                while (true) {

                    try {
                        intCatch = Integer.parseInt(txtCatch);

                        if ((intCatch > 0) && (intCatch < 5)) {

                            listener.messageAction("vLanes", lanes[0].gethLanes(), intCatch);
                            vLanes = intCatch;
                            carsDisplay = new CarsDisplay(lanes);
                            display.removeAll();
                            display.add(carsDisplay);
                            pack();
                            break;

                        } else {

                            vLanesTxt.setText("INVALID ENTRY::"+ txtCatch+"::: Eenter a Value from 1-3" );

                            break;
                        }

                    } catch (Exception p) {
                        vLanesTxt.setText("INVALID ENTRY::"+ txtCatch+":: Enter a Value from 1-3" );
                        break;
                    }
                }
            }
        });

        hProb.addChangeListener(new ChangeListener() {

            public void stateChanged(ChangeEvent e) {

                JSlider source = (JSlider) e.getSource();
                if (!source.getValueIsAdjusting()) {

                    int newProb = (int) source.getValue();
                    listener.messageAction("hLanes", newProb);
                }
            }
        });

        vProb.addChangeListener(new ChangeListener() {

            public void stateChanged(ChangeEvent e) {

                JSlider source = (JSlider) e.getSource();
                if (!source.getValueIsAdjusting()) {

                    int newProb = (int) source.getValue();
                    listener.messageAction("vLanes", newProb);
                }
            }
        });

        pack();

        this.addWindowListener(new WindowAdapter() {

            @Override
            public void windowClosing(WindowEvent e) {

                System.out.println("Please use Exit button");
                System.exit(0);
            }
        });
    }

    /**
     *Public method that passes value from main through to display
     * @param value is of boolean type
     */
    public void setPaused(boolean value) {

        carsDisplay.setPaused(value);
    }

    /**
     *Public method that passes value to main through from display
     * @return value is of boolean type
     */
    public boolean getPaused() {

        boolean z = carsDisplay.getPaused();
        return z;
    }

    /**
     *Public method that passes MessageListener object reference into this object
     * @param task is of MessageListener type
     */
    public void addMessageListener(MessageListener task) {

        listener = task;
//        carsDisplay.addMessageListener(task);
    }

    /**
     *Public method that passes lane[] reference into this object
     * @param newLanes is of  Lane[] type
     */
    public void newLanes(Lane[] newLanes) {

        lanes = newLanes;
    }
}
